﻿// Sheego.Service.X400
// Copyright(C) 2015 Schwab Versand GmbH
//
// This source file is subject to the Microsoft Public License(Ms-PL).
// http://www.opensource.org/licenses/ms-pl.html
// All other rights reserved.
using Sheego.Service.X400.Job.Shared;
using Sheego.Service.X400.Job.Shared.BO;
using Sheego.Service.X400.Job.Shared.Locator;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Sheego.Service.X400.Job.Impl
{
    class FileManager : IFileManager
    {


        private IJobConfiguration JobConfiguration;
        private static Regex ExtensionRegex= new Regex(@"(^\.hdr$)|(^\.[0-9]{3,3}$)");

        public FileManager(IJobConfiguration jobConfiguration)
        {
            JobConfiguration = jobConfiguration;
        }


        #region IFileManager Members

        public void CleanupTempDirectory()
        {

            //CleanUp Data/Temp
            foreach (FileInfo file in new DirectoryInfo(JobConfiguration.UAFIWorkingPath).GetFiles())
            {

                if(file.Name.Equals(Constants.CommandFileName))
                    file.Delete();

                if (file.Name.Equals(Constants.ResponseFileName))
                    file.Delete();

                if (file.Name.StartsWith(Constants.TempPrefix))
                    file.Delete();

                if (ExtensionRegex.Match(file.Extension).Success)
                    file.Delete();

            }

        }

        public void CreateCommandTextFile(string Command)
        {
            if (String.IsNullOrWhiteSpace(Command))
                throw new ArgumentNullException("Command");

            var Path = JobConfiguration.UAFIWorkingPath + @"\" + Constants.CommandFileName;
            File.WriteAllLines(Path,new List<String>(){ Command });
        }

        public void AppendCacheFile(string MessageId)
        {
            if (String.IsNullOrWhiteSpace(MessageId))
                throw new ArgumentNullException("MessageId");
            var Path = JobConfiguration.UAFIWorkingPath + @"\" + Constants.CacheFileName;
            File.AppendAllLines(Path, new List<String>() { MessageId });
        }


        public void AppendLogFile(string Key, DateTime dateTime, string Message)
        {
            if (String.IsNullOrWhiteSpace(Key))
                throw new ArgumentNullException("Key");
            if (dateTime == null)
                throw new ArgumentNullException("Key");
            if (Message == null) //Empty nicht sinnvoll aber erlaubt
                throw new ArgumentNullException("Message");


            var Path = JobConfiguration.UAFIWorkingPath + @"\" + Constants.LogFileName;
            var LogEntry = String.Format("{0} - {1:yyyy-MM-dd HH:mm:ss} - {2}", Key, dateTime, Message);
            File.AppendAllLines(Path, new List<String>() { LogEntry });
        }

        public IList<string> ReadResponseTextFile()
        {
            return ReadTextFile(Constants.ResponseFileName);
        }

        public IList<string> ReadCacheFile()
        {
            
            var Path = JobConfiguration.UAFIWorkingPath + @"\" + Constants.CacheFileName;
            
            if (!File.Exists(Path))
               return new List<String>();

            return File.ReadAllLines(Path).ToList();

        }

        public IList<string> ListFileNamesForMessageId(string MessageId)
        {
            if (String.IsNullOrWhiteSpace(MessageId))
                throw new ArgumentNullException("MessageId");

            var List = new List<String>();
            foreach (var filePath in Directory.GetFiles(JobConfiguration.UAFIWorkingPath,MessageId+".*"))
            {
                var Name = Path.GetFileName(filePath);
                var Extension = Path.GetExtension(filePath);
                if (ExtensionRegex.Match(Extension).Success)
                    List.Add(Name);
            }


            return List;
        }

        public IContentType ProbeContentType(byte[] buffer)
        {
            if (buffer == null || buffer.Length == 0)
                throw new ArgumentNullException("buffer");



            //ASCII - TextFile ??? 
            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
            var text = enc.GetString(buffer);


            var ediParser = JobLocator.GetEDIFACTParser();

            var ContentType = ediParser.Parse(text);


            if (ContentType == null)
            {
                ContentType = JobLocator.GetContentType();
                ContentType.MIMEType = "unknown";
                ContentType.SubType = "unknown";
            }

            return ContentType;
        }

        public byte[] ReadFile(string FileName)
        {
            if (String.IsNullOrWhiteSpace(FileName))
                throw new ArgumentNullException("FileName");

            var Path = JobConfiguration.UAFIWorkingPath + @"\" + FileName;
            if (!File.Exists(Path))
                throw new FileNotFoundException(Path);

            return File.ReadAllBytes(Path);
        }

        public IList<string> ReadTextFile(string FileName)
        {
            if (String.IsNullOrWhiteSpace(FileName))
                throw new ArgumentNullException("FileName");

            var Path = JobConfiguration.UAFIWorkingPath + @"\" + FileName;
            if (!File.Exists(Path))
                throw new FileNotFoundException(Path);

            return File.ReadAllLines(Path).ToList();
        }

        public void WriteFile(string FilePath, byte[] buffer)
        {
            if (String.IsNullOrWhiteSpace(FilePath))
                throw new ArgumentNullException("FilePath");

            if (buffer == null)
                throw new ArgumentNullException("buffer");

            File.WriteAllBytes(FilePath, buffer);
        }

        public void WriteTextFile(string FilePath, string content)
        {
            if (String.IsNullOrWhiteSpace(FilePath))
                throw new ArgumentNullException("FilePath");

            if (content == null)
                throw new ArgumentNullException("content");

            File.WriteAllText(FilePath, content);
        }

        public string CreateUniquePattern(DateTime time)
        {
            // Pattern Version A  - {DateTime}_{PseudoRandomNumber}

            // Zufallszahlen erzeugen
            RNGCryptoServiceProvider csp = new RNGCryptoServiceProvider();
            byte[] numbers = new Byte[4];
            csp.GetBytes(numbers);

            return String.Format("{0}_{1}", time.ToString("yyyyMMddHHmmssfff"), BitConverter.ToString(numbers).Replace("-", string.Empty));

        }

        public string CreateTempFileName(string PostFileName)
        {
            if (String.IsNullOrWhiteSpace(PostFileName))
                throw new ArgumentNullException("PostFileName");

            return JobConfiguration.UAFIWorkingPath + @"\" + Constants.TempPrefix + CreateUniquePattern(DateTime.Now) + PostFileName;
        }

        #endregion
    }
}
